// Do not remove the include below
#include "LibMorse.h"
#include "MorseEncoder.h"


Morse::Morse(int pin)
	: _pin(pin)
{
	pinMode(_pin, OUTPUT);
}

void Morse::dot()
{
	digitalWrite(_pin, HIGH);
	::delay(_DOT_DELAY);
	digitalWrite(_pin, LOW);
	//::delay(_DOT_DELAY);
}

void Morse::dash()
{
	digitalWrite(_pin, HIGH);
	::delay(_DASH_DELAY);
	digitalWrite(_pin, LOW);
	//::delay(_DOT_DELAY);
}

void Morse::letter_break()
{
	::delay(_LETTER_DELAY);
}

void Morse::word_break()
{
	::delay(_WORD_DELAY);
}

void Morse::SOS()
{
//	dot(); dot(); dot();
//	dash(); dash(); dash();
//	dot(); dot(); dot();
//
//	delay();

	const SYMBOL SOS[] =
	{
		DOT, DOT, DOT,
		LETTER_BREAK,
		DASH, DASH, DASH,
		LETTER_BREAK,
		DOT, DOT, DOT,
		WORD_BREAK,
		EOC
	};

	send(static_cast<const SYMBOL*>(SOS));
}

bool Morse::send(const SYMBOL* code, int len)
{
	if (code)
	{
		for (int i = 0; i < len; i++)
		{
			if (code[i] == EOC)
			{
				return true;
			}

			send_symbol(code[i], code[i+1]);
		}
	}

	return false;
}

//bool Morse::send(SYMBOL* code)
//{
//	return send((const SYMBOL*) code);
//}

bool Morse::send(const SYMBOL* code)
{
	while (code)
	{
		SYMBOL current = *code;
		if (current == EOC)
		{
			return true;
		}

		code++;

		SYMBOL next = *code;
		send_symbol(current, next);
	}
	return false;
}

bool Morse::send(const char * str)
{
	MorseEncoder encoder(str);

	const SYMBOL* aEncoding = encoder.Encoding();
	if (aEncoding)
	{
		return send(aEncoding);
	}

	return false;
}

//const SYMBOL* Morse::transcode(const char c, const char n)
//{
//	if (c != ' ')
//	{
//		// its a letter, transcode the character
//
//		// what comes after current?
//		switch (n)
//		{
//		case ' ':	//space
//		case '\t':	//tab
//			// this is last letter of word
//			// append word_break
//			break;
//		case '\0':
//			// null terminator, this is last letter of code
//			// append word_break;
//		case EOC:
//		default:	//letter
//			// theres a letter after this one, we're in a word
//			// append letter break
//			break;
//		}
//	}
//
//	// new comment test
//
//	return NULL;
//}

void Morse::send_symbol(const SYMBOL symbol)
{
	switch (symbol)
	{
		case DOT: dot(); break;
		case DASH: dash(); break;
		case WORD_BREAK: word_break(); break;
		case LETTER_BREAK: letter_break(); break;
		case EOC: /* nothing */ break;
	}
}

void Morse::send_symbol(const SYMBOL symbol, const SYMBOL next)
{
	switch (symbol)
	{
		case DOT: dot(); break;
		case DASH: dash(); break;
		case WORD_BREAK: word_break(); break;
		case LETTER_BREAK: letter_break(); break;
		case EOC:	/* nothing */ break;
	}

	if (next == DOT || next == DASH)
	{
		// include a short delay (duration of a single dot) for in between symbols
		::delay(_DOT_DELAY);
	}
}
